import os
import json
import time
from openai import OpenAI

# 初始化OpenAI客户端（单例模式，避免重复创建）
client = OpenAI(
    base_url="https://ark.cn-beijing.volces.com/api/v3",
    api_key="330f54b7-915b-48a9-9599-c5e47c118cb5"  # 建议改为环境变量：os.getenv("ARK_API_KEY")
)


def generate_solutions_list(question: str) -> dict:
    """生成按难易程度排序的解决办法列表（串行处理，单请求）"""
    system_prompt = """
    背景：拓竹科技3D打印用户提出问题。
    目标：根据用户问题，按用户实操难易程度（容易→中等→困难）列出可能的解决办法。
    步骤：
    1. 分析问题：识别现象，分析全部的，最常见且互斥的原因（硬件、软件设置、材料、操作错误等）。
    2. 列出解决办法：为每个原因分配独立、具体的解决办法，避免重叠。
    3. 输出格式：严格遵循示例，必须包含"困难"等级（仅一个）。

    严格要求：
    - 输出必须是纯净的JSON字符串，无任何多余文字、注释或格式说明
    - 确保逗号、引号、括号完全匹配，键名和字符串值必须用双引号包裹
    - 数组和对象末尾不得有多余逗号

    案例格式：
    ```json
    {
      "原始问题": "用户原始问题",
      "解决办法列表": [
        {
          "难度等级": "容易",
          "对应原因": "具体原因",
          "操作步骤": ["步骤1", "步骤2"]
        },
        {
          "难度等级": "困难",
          "对应原因": "具体原因",
          "操作步骤": ["步骤1", "步骤2"]
        }
      ]
    }
    {
      "原始问题": "我的X1C打印机使用PAHT CF碳纤耗材时，系统提示该耗材与当前喷嘴不兼容",
      "解决办法列表": [
        {
          "难度等级": "容易",
          "对应原因": "打印机未识别到硬质合金喷嘴",
          "操作步骤": [
            "检查打印机是否安装了专用的硬质合金喷嘴（标配为不锈钢喷嘴）",
            "在打印机设置中手动选择硬质合金喷嘴类型"
          ]
        },
        {
          "难度等级": "中等",
          "对应原因": "固件版本过旧导致兼容性识别错误",
          "操作步骤": [
            "进入打印机设置菜单，检查当前固件版本",
            "连接网络并升级到最新固件版本",
            "重启打印机后重新尝试打印"
          ]
        },
        {
          "难度等级": "困难",
          "对应原因": "需要更换物理喷嘴硬件",
          "操作步骤": [
            "购买原厂硬质合金喷嘴组件（型号：Bambu Lab Hardened Steel Nozzle Kit）",
            "按照官方教程拆卸原有不锈钢喷嘴",
            "安装新的硬质合金喷嘴并进行校准",
            "在打印机设置中确认喷嘴类型已更新"
          ]
        }
      ]
    }
    ```
    """

    try:
        response = client.chat.completions.create(
            model="deepseek-v3-1-250821",
            messages=[
                {"role": "system", "content": system_prompt.strip()},
                {"role": "user", "content": f"用户问题：{question}"}
            ]
        )

        content = response.choices[0].message.content.strip()
        # 清洗内容：去除换行和首尾多余引号
        content = content.replace('\n', '').strip()
        if content.startswith('"') and content.endswith('"'):
            content = content[1:-1]
        # 调试：打印生成的JSON内容
        print(f"生成的JSON内容: {content}")

        result = json.loads(content)

        # 格式验证（保持不变）
        if "原始问题" not in result or "解决办法列表" not in result:
            raise KeyError("缺少'原始问题'或'解决办法列表'字段")
        if not isinstance(result["解决办法列表"], list) or len(result["解决办法列表"]) < 2:
            raise ValueError("解决办法列表格式错误或数量不足（需≥2项）")
        difficult_items = [item for item in result["解决办法列表"] if item.get("难度等级") == "困难"]
        if len(difficult_items) != 1:
            raise ValueError("解决办法列表中必须且只能包含1个'困难'等级的解决办法")

        return result
    except json.JSONDecodeError as e:
        return {
            "原始问题": question,
            "解决办法列表": [
                {"难度等级": "错误", "对应原因": f"JSON解析失败：{str(e)}，原始内容：{content}", "操作步骤": []}]
        }
    except Exception as e:
        return {
            "原始问题": question,
            "解决办法列表": [{"难度等级": "错误", "对应原因": f"生成失败：{str(e)}", "操作步骤": []}]
        }
def generate_revised_question(original_question: str, solutions: list) -> str:
    """生成修正后的问题（确保包含尝试办法）"""
    # 筛选非困难的解决办法（容易/中等）
    non_difficult_solutions = [
        sol for sol in solutions
        if sol.get("难度等级") in ["容易", "中等"]
    ]

    # 即使没有非困难办法，也明确说明"未尝试方法"
    if not non_difficult_solutions:
        return json.dumps({
            "尝试办法问题": f"{original_question}，尚未尝试任何解决方法，该如何处理？"
        }, ensure_ascii=False)

    # 构建已尝试方法的简洁描述（优化：更清晰的步骤描述）
    tried_methods = []
    for sol in non_difficult_solutions:
        reason = sol.get("对应原因", "未知原因")
        steps = "；".join(sol.get("操作步骤", []))  # 保留完整步骤，确保信息充分
        tried_methods.append(f"针对{reason}，已尝试：{steps}")

    system_prompt = """
    角色：资深拓竹科技3D打印用户。
    任务：用第一人称将已尝试的解决办法融入原问题，生成新问题。
    要求：
    1. 保留原始问题核心意图；
    2. 明确体现已尝试的所有方法（不省略关键步骤）；
    3. 输出格式必须为JSON，仅包含键"尝试办法问题"，值为重构后的问题。
    示例输出：{"尝试办法问题": "我的X1C打印机使用PAHT CF碳纤耗材时提示喷嘴不兼容，已检查并确认安装了硬质合金喷嘴且在设置中手动选择该类型，同时升级了最新固件版本，但问题依旧，怎么办？"}
    """

    try:
        user_content = f"原始问题：{original_question}\n已尝试方法：{'; '.join(tried_methods)}"
        response = client.chat.completions.create(
            model="deepseek-v3-1-250821",
            messages=[
                {"role": "system", "content": system_prompt.strip()},
                {"role": "user", "content": user_content}
            ]
        )
        # 确保返回结果是JSON格式
        return response.choices[0].message.content.strip()
    except Exception as e:
        return json.dumps({
            "尝试办法问题": f"{original_question}（已尝试：{'; '.join(tried_methods)}，但未解决，错误：{str(e)}）"
        }, ensure_ascii=False)


def generate_customer_service_reply(revised_question: str, difficult_solution: dict) -> str:
    """生成客服回答（基于修正后的问题和困难办法）"""
    system_prompt = """
    角色：拓竹科技专业客服。
    任务：针对用户修正后的问题（含已尝试方法）和困难解决办法，生成专业回答。
    要求：
    1. 先呼应用户已尝试的方法（表示理解）；
    2. 基于困难办法的操作步骤，给出可执行的解决方案；
    3. 不要再次描述问题，直接给出答案，语言简洁、专业，避免冗余；
    4. 输出格式为JSON，包含键"客服回答"，值为客服回答。
    示例输出：{"客服回答": "建议更换原厂硬质合金喷嘴组件（型号：Bambu Lab Hardened Steel Nozzle Kit），具体步骤为：按照官方教程拆卸原有不锈钢喷嘴，安装新喷嘴并校准，最后在设置中确认喷嘴类型已更新。"}
    """

    try:
        # 提取困难办法的核心信息
        reason = difficult_solution.get("对应原因", "未知原因")
        steps = difficult_solution.get("操作步骤", [])
        steps_summary = "；".join(steps) if steps else "无具体步骤"

        user_content = f"用户修正后问题：{revised_question}\n困难解决办法：{reason}，步骤：{steps_summary}"
        response = client.chat.completions.create(
            model="deepseek-v3-1-250821",
            messages=[
                {"role": "system", "content": system_prompt.strip()},
                {"role": "user", "content": user_content}
            ]
        )
        return response.choices[0].message.content.strip()
    except Exception as e:
        return json.dumps({
            "尝试办法问题": f"您的问题需要通过以下步骤解决：{steps_summary}（因系统原因表述简化，错误：{str(e)}）"
        }, ensure_ascii=False)


def process_non_unique_questions(input_questions: list) -> list:
    """处理所有“解决办法不唯一”的问题（串行处理，避免并行冲突）"""
    final_results = []
    total = len(input_questions)

    for idx, question in enumerate(input_questions, 1):
        print(f"开始处理第{idx}/{total}个问题：{question[:50]}...")
        start_time = time.time()

        try:
            # 步骤1：生成解决办法列表（串行执行，完成后再进入下一步）
            solutions_data = generate_solutions_list(question)
            solutions_list = solutions_data["解决办法列表"]

            # 步骤2：提取唯一的困难办法
            difficult_solution = next(
                (sol for sol in solutions_list if sol.get("难度等级") == "困难"),
                {"对应原因": "未找到困难办法", "操作步骤": []}
            )

            # 步骤3：生成修正后的问题（依赖步骤1结果，串行执行）
            revised_question_json = generate_revised_question(question, solutions_list)
            # 解析JSON确保格式正确
            revised_question = json.loads(revised_question_json).get("尝试办法问题", question)

            # 步骤4：生成客服回答（依赖步骤2和3结果，串行执行）
            cs_reply = generate_customer_service_reply(revised_question, difficult_solution)

            # 构建最终结果
            final_item = {
                "原始问题": question,
                "解决办法列表": solutions_list,
                "修正后的问题（含尝试方法）": revised_question,
                "客服回答": cs_reply
            }
            final_results.append(final_item)

        except Exception as e:
            print(f"第{idx}个问题处理出错：{str(e)}")
            final_results.append({
                "原始问题": question,
                "错误信息": f"处理失败：{str(e)}"
            })

        elapsed = round(time.time() - start_time, 2)
        print(f"第{idx}个问题处理完成，耗时{elapsed}秒\n")

        # 可选：添加请求间隔，避免API频率限制
        time.sleep(1)

    return final_results


if __name__ == "__main__":
    # 配置文件路径
    input_json_path = r"E:\TUOZHU\问题唯一性判断结果json.json"
    output_json_path = "3D打印问题处理结果.json"

    # 步骤1：读取并筛选"解决办法是否唯一"为"否"的问题（提取用户问题字符串）
    non_unique_questions = []
    try:
        with open(input_json_path, 'r', encoding='utf-8') as f:
            input_data = json.load(f)

        # 验证输入数据格式
        if not isinstance(input_data, list):
            raise ValueError("输入JSON文件根节点必须是列表")

        # 提取"用户问题"字段（确保输入是字符串）
        for item in input_data:
            if isinstance(item, dict) and item.get("解决办法是否唯一") == "否":
                user_question = item.get("用户问题", "").strip()
                if user_question:  # 过滤空问题
                    non_unique_questions.append(user_question)

        print(f"成功筛选出{len(non_unique_questions)}个解决办法不唯一的问题")

    except FileNotFoundError:
        print(f"错误：未找到输入文件 {input_json_path}")
        exit(1)
    except json.JSONDecodeError:
        print(f"错误：输入文件 {input_json_path} 不是有效的JSON格式")
        exit(1)
    except Exception as e:
        print(f"读取筛选问题时出错：{str(e)}")
        exit(1)

    # 步骤2：串行处理所有非唯一问题（避免并行请求冲突）
    if non_unique_questions:
        results = process_non_unique_questions(non_unique_questions)

        # 步骤3：保存结果
        with open(output_json_path, "w", encoding="utf-8") as f:
            json.dump(results, f, ensure_ascii=False, indent=2)
        print(f"所有问题处理完成，结果已保存至：{output_json_path}")
    else:
        print("没有需要处理的解决办法不唯一的问题")